package service

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"go-server-demo/ent"
	"go-server-demo/internal/repository"

	"github.com/go-redis/redis/v8"
)

type UserService struct {
	repo  *repository.UserRepository
	redis *redis.Client
}

func NewUserService(repo *repository.UserRepository, redis *redis.Client) *UserService {
	return &UserService{
		repo:  repo,
		redis: redis,
	}
}

func (s *UserService) CreateUser(ctx context.Context, req *repository.CreateUserRequest) (*ent.User, error) {
	// 检查用户名是否已存在
	existingUser, err := s.repo.GetByUsername(ctx, req.Username)
	if err == nil && existingUser != nil {
		return nil, fmt.Errorf("username already exists")
	}

	// 创建用户
	user, err := s.repo.Create(ctx, req)
	if err != nil {
		return nil, err
	}

	// 清除用户列表缓存
	s.clearUserListCache(ctx)

	return user, nil
}

func (s *UserService) GetUser(ctx context.Context, id int) (*ent.User, error) {
	// 尝试从Redis获取
	cacheKey := fmt.Sprintf("user:%d", id)
	cached, err := s.redis.Get(ctx, cacheKey).Result()
	if err == nil {
		var user ent.User
		if err := json.Unmarshal([]byte(cached), &user); err == nil {
			return &user, nil
		}
	}

	// 从数据库获取
	user, err := s.repo.GetByID(ctx, id)
	if err != nil {
		return nil, err
	}

	// 存入Redis缓存
	userData, _ := json.Marshal(user)
	s.redis.Set(ctx, cacheKey, userData, time.Hour)

	return user, nil
}

func (s *UserService) UpdateUser(ctx context.Context, id int, req *repository.UpdateUserRequest) (*ent.User, error) {
	user, err := s.repo.Update(ctx, id, req)
	if err != nil {
		return nil, err
	}

	// 清除缓存
	cacheKey := fmt.Sprintf("user:%d", id)
	s.redis.Del(ctx, cacheKey)
	s.clearUserListCache(ctx)

	return user, nil
}

func (s *UserService) DeleteUser(ctx context.Context, id int) error {
	err := s.repo.Delete(ctx, id)
	if err != nil {
		return err
	}

	// 清除缓存
	cacheKey := fmt.Sprintf("user:%d", id)
	s.redis.Del(ctx, cacheKey)
	s.clearUserListCache(ctx)

	return nil
}

func (s *UserService) ListUsers(ctx context.Context, limit, offset int) ([]*ent.User, error) {
	// 尝试从Redis获取
	cacheKey := fmt.Sprintf("users:list:%d:%d", limit, offset)
	cached, err := s.redis.Get(ctx, cacheKey).Result()
	if err == nil {
		var users []*ent.User
		if err := json.Unmarshal([]byte(cached), &users); err == nil {
			return users, nil
		}
	}

	// 从数据库获取
	users, err := s.repo.List(ctx, limit, offset)
	if err != nil {
		return nil, err
	}

	// 存入Redis缓存
	usersData, _ := json.Marshal(users)
	s.redis.Set(ctx, cacheKey, usersData, 30*time.Minute)

	return users, nil
}

func (s *UserService) clearUserListCache(ctx context.Context) {
	// 清除所有用户列表缓存
	keys, err := s.redis.Keys(ctx, "users:list:*").Result()
	if err == nil && len(keys) > 0 {
		s.redis.Del(ctx, keys...)
	}
}
